/*
 * Copyright (c) 2020-2099 the original author or authors. All rights reserve.
 */
package org.tianyun.cloud.autoconfigure;

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
import org.tianyun.cloud.context.AppContext;

import java.util.ArrayList;
import java.util.List;

/**
 * CloudImportSelector
 * <p>
 *
 * @author ebert_chan
 */
public class CloudImportSelector implements ImportSelector {

    // @formatter:off
	public final Class<?>[] importClasses = {
		AppContext.class
	};
	
	private final String[] exts = {
		"org.tianyun.cloud.config.autoconfigure.CloudConfigAutoConfiguration",
		"org.tianyun.cloud.datasource.autoconfigure.DataSourceAutoConfiguration",
		"org.tianyun.cloud.mybatis.autoconfigure.MybatisAutoConfiguration",
		"org.tianyun.cloud.data.redis.autoconfigure.RedisContainerAutoConfiguration",
		"org.tianyun.cloud.amqp.rabbitmq.autoconfigure.RabbitMqAutoConfiguration",
		"org.tianyun.cloud.web.autoconfigure.CloudWebAutoConfiguration",
		"org.tianyun.cloud.security.autoconfigure.SecurityAutoConfiguration",
		"org.tianyun.cloud.rest.autoconfigure.CloudRestAutoConfiguration",
		"org.tianyun.cloud.openfeign.autoconfigure.OpenFeignAutoConfiguration"
	};
	
	// @formatter:on

    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {

        List<String> classNames = new ArrayList<>(importClasses.length + exts.length);

        for (int i = 0; i < importClasses.length; i++) {
            classNames.add(importClasses[i].getName());
        }

        for (int i = 0; i < exts.length; i++) {
            if (!isPresent(exts[i])) {
                continue;
            }
            classNames.add(exts[i]);
        }
        return classNames.stream().toArray(String[]::new);
    }

    public boolean isPresent(String className) {
        ClassLoader classLoader = this.getClass().getClassLoader();
        try {
            forName(className, classLoader);
            return true;
        } catch (Throwable ex) {
            return false;
        }
    }

    private Class<?> forName(String className, ClassLoader classLoader) throws ClassNotFoundException {
        if (classLoader != null) {
            return classLoader.loadClass(className);
        }
        return Class.forName(className);
    }

}
